﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Common.Attributes;
using Common.Base;
using Common.Base.Result;
using Common.Exceptions;
using Common.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Model.Dto;
using Model.Entity;

namespace Repository
{
    [Component(ServiceType = typeof(IUserInfoRepository))]
    public class UserInfoRepositoryImpl : IUserInfoRepository
    {
        private readonly ILogger<UserInfoRepositoryImpl> _logger;
        private readonly IServiceScopeFactory _scopeFactory;
        // private readonly TestDbContext _db;

        public UserInfoRepositoryImpl(ILogger<UserInfoRepositoryImpl> logger, IServiceScopeFactory scopeFactory)
        {
            _logger = logger;
            _scopeFactory = scopeFactory;
        }

        #region Demo

        public async Task<PageData<UserInfoDto>> SelectUserInfoPage(UserInfoPageParamDto dto)
        {
            var page = new PageData<UserInfoDto>();
            using var scope = _scopeFactory.CreateScope();
            await using var _db = scope.ServiceProvider.GetRequiredService<TestDbContext>();
            var query = _db.TestUsers.Where(p => p.IsDeleted == 0);
            // query = query.Where(p => p.UserName.Contains(dto.UserName.Trim()));
            page.Total = query.Count();
            var list = await query.OrderByDescending(p => p.CreateTime)
                .Skip((dto.PageIndex - 1) * dto.PageSize)
                .Take(dto.PageSize).ToListAsync();
            page.Rows = list.MapToList<UserInfo, UserInfoDto>();
            return page;
        }

        public async Task<List<UserInfoDto>> SelectUserInfos(UserInfoDto dto)
        {
            using var scope = _scopeFactory.CreateScope();
            await using var _db = scope.ServiceProvider.GetRequiredService<TestDbContext>();
            var query = _db.TestUsers.Where(p => p.IsDeleted == 0);
            // query = query.Where(p => p.UserName.Contains(dto.UserName.Trim()));
            var list = await query.OrderByDescending(p => p.CreateTime).ToListAsync();
            return list.MapToList<UserInfo, UserInfoDto>();
        }

        public async Task<UserInfoDto> SelectUserInfo(UserInfoDto dto)
        {
            using var scope = _scopeFactory.CreateScope();
            await using var _db = scope.ServiceProvider.GetRequiredService<TestDbContext>();
            var item = await _db.TestUsers.FirstOrDefaultAsync(p => p.IsDeleted == 0 && p.KeyId == dto.KeyId);
            var userDto = item.MapTo<UserInfoDto>();
            return userDto;
        }

        public async Task<bool> InsertUserInfo(UserInfoDto dto)
        {
            using var scope = _scopeFactory.CreateScope();
            await using var _db = scope.ServiceProvider.GetRequiredService<TestDbContext>();
            var entity = dto.MapTo<UserInfo>();
            _db.TestUsers.Add(entity);
            var saveChanges = await _db.SaveChangesAsync();
            return saveChanges > 0;
        }

        public async Task<bool> UpdateUserInfo(UserInfoDto dto)
        {
            using var scope = _scopeFactory.CreateScope();
            await using var _db = scope.ServiceProvider.GetRequiredService<TestDbContext>();
            var item = _db.TestUsers.FirstOrDefault(p => p.IsDeleted == 0 && p.KeyId == dto.KeyId);
            item.SetModelValue(dto);
            // item.UpdateTime = DateTime.Now;
            // _db.Update(item);
            var saveChanges = await _db.SaveChangesAsync();
            // _logger.LogInformation("修改用户成功 " + saveChanges);
            return saveChanges > 0;
        }

        public Task<bool> TokenTest()
        {
            throw new TokenException("token失效");
        }

        public Task<bool> CustomTest()
        {
            throw new CustomException("custom异常");
        }

        #endregion
    }
}